package com.interauto.service;

import com.interauto.Interface.HttpAutoClientInterface;
import com.interauto.bean.httpinfo.HttpRequestBean;
import com.interauto.bean.httpinfo.HttpResPonseBean;
import com.interauto.util.AutoStringUtils;
import com.interauto.util.HttpAutoUtils;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.UnknownHostException;
import java.util.*;


/**
 * 具体请求http和get的实现
 */
@Component
public class HttpAutoClientService implements HttpAutoClientInterface {
    private static final Logger logger= LoggerFactory.getLogger(HttpAutoClientService.class);
    private static final String encode="utf-8";

    @Autowired
    private HttpClientPool httpClientPool;

    public HttpResPonseBean autoget(HttpRequestBean httpRequestBean) {
        if(httpRequestBean == null){
            logger.info("---- >>> autoget httpRequestBean is null");
            return null;
        }
        logger.info("autoget response info is ---->"+httpRequestBean.toString());
        //CloseableHttpClient httpClient=httpClientPool.getHttpClient();

        HttpResPonseBean httpResPonseBean=new HttpResPonseBean();
        try{
            String url=httpRequestBean.getHttpurl();
            Map<String,String> mapparam=HttpAutoUtils.getHeaderMap(httpRequestBean.getHttpparam()); //将get参数处理拼接到url上面
            url=getUrlParam(url,mapparam);
            URIBuilder urlBuilder=new URIBuilder(url);
            HttpGet httpGet=new HttpGet(urlBuilder.build());
            httpGet.setHeaders(getRequestHeaders(httpRequestBean));

            CloseableHttpClient httpClient=HttpClientUtil.getHttpClient(url);

            CloseableHttpResponse response=httpClient.execute(httpGet);
            httpResPonseBean=new HttpResPonseBean();
            setresponseinfo(httpResPonseBean,response);
            return httpResPonseBean;
        }
        catch (UnknownHostException e){
            logger.error("autoget is UnknownHostException error --->"+e);
            httpResPonseBean=new HttpResPonseBean();
            httpResPonseBean.setRescode(404);
            httpResPonseBean.setResinfo(e.toString());
            return httpResPonseBean;
        }
        catch (Exception e){
            e.printStackTrace();
            httpResPonseBean=new HttpResPonseBean();
            httpResPonseBean.setRescode(600);
            httpResPonseBean.setResinfo(e.toString());
            logger.error("autoget is system error --->"+e);
        }
        return null;
    }

    public HttpResPonseBean autopost(HttpRequestBean httpRequestBean) {
        if(httpRequestBean == null){
            logger.info("---- >>> autopost httpRequestBean is null");
            return null;
        }
        logger.info("autopost request info is ---->"+httpRequestBean.toString());
        //CloseableHttpClient httpClient=httpClientPool.getHttpClient();
        HttpResPonseBean httpResPonseBean=new HttpResPonseBean();
        try{
            String url=httpRequestBean.getHttpurl();
            URIBuilder urlBuilder=new URIBuilder(url);
            HttpPost httpPost=new HttpPost(urlBuilder.build());
            httpPost.setHeaders(getRequestHeaders(httpRequestBean));
            httpPost.setEntity(getStringEntity(httpRequestBean));

            CloseableHttpClient httpClient=HttpClientUtil.getHttpClient(url);

            CloseableHttpResponse response=httpClient.execute(httpPost);
            setresponseinfo(httpResPonseBean,response);
            return httpResPonseBean;
        }
        catch (UnknownHostException e){
            logger.error("autopost is UnknownHostException error --->"+e);
            httpResPonseBean=new HttpResPonseBean();
            httpResPonseBean.setRescode(404);
            httpResPonseBean.setResinfo(e.toString());
            return httpResPonseBean;
        }
        catch (Exception e){
            httpResPonseBean=new HttpResPonseBean();
            httpResPonseBean.setRescode(600);
            httpResPonseBean.setResinfo(e.toString());
            e.printStackTrace();
            logger.error("autopost is system error --->"+e);
        }
        return null;
    }


    /**
     * 给post请求用的，处理请求参数相关
     * @param httpRequestBean 请求对象
     * @return http请求参数对象
     */
    private HttpEntity getStringEntity(HttpRequestBean httpRequestBean){
        if(httpRequestBean == null || StringUtils.isEmpty(httpRequestBean.getHttpparam())){
            return null;
        }
        int postparamtype=httpRequestBean.getPostparamtype()!=null?httpRequestBean.getPostparamtype():0;
        HttpEntity entity=null;
        String httppram=httpRequestBean.getHttpparam();
        switch (postparamtype){
            case 1:
                entity=new StringEntity(httppram,encode);
                return entity;
            case 2:
                List<NameValuePair> valuePairs=getValuelist(httppram);
                if(valuePairs == null || valuePairs.isEmpty()){
                    return entity;
                }
                try{
                    entity=new UrlEncodedFormEntity(valuePairs,encode);
                }
                catch (Exception e){
                    e.printStackTrace();
                    logger.error("UrlEncodedFormEntity is system error --->"+e);
                }
                return entity;
            default:
                logger.info("postparamtype is error ---->"+httpRequestBean.toString());
        }
        return null;

    }



    private List<NameValuePair> getValuelist(String httpparam){
        if(StringUtils.isEmpty(httpparam)){
            return null;
        }
        Map<String,String> valuemap= AutoStringUtils.getMaptoJson(httpparam);
        if(valuemap == null || valuemap.isEmpty()){
            return null;
        }
        List<NameValuePair> valuePairs=new ArrayList<>();
        for(String str:valuemap.keySet()){
            valuePairs.add(new BasicNameValuePair(str,valuemap.get(str)));
        }
        return valuePairs;
    }

    /**
     * 往请求里添加添加header，包括cookie
     * @param httpRequestBean 请求对象
     * @return 要请求的header
     */
    private Header[] getRequestHeaders(HttpRequestBean httpRequestBean){
        if(httpRequestBean == null){
            return null;
        }
        List<Header> headerList=new ArrayList<>();
        int postparamtype=httpRequestBean.getPostparamtype()!=null?httpRequestBean.getPostparamtype():0;
        switch (postparamtype){
            case 1:
                headerList.add(new BasicHeader("Content-Type","application/json"));
                break;
            case 2:
                headerList.add(new BasicHeader("Content-Type","application/x-www-form-urlencoded"));
                break;
            default:
                break;
        }
        Map<String,String> headermaps=httpRequestBean.getHttpheader();
        Map<String,String> headercooks=httpRequestBean.getHttpcookie();
        if(headermaps == null && headercooks == null){
            Header[] headers=new Header[headerList.size()];
            return headerList.toArray(headers);
        }
        for(String headerkey:headermaps.keySet()){
            headerList.add(new BasicHeader(headerkey,headermaps.get(headerkey)));
        }
        if(headercooks!=null && headercooks.size()>0){
            headerList.add(new BasicHeader("Cookie",HttpAutoUtils.getCookievalue(headercooks)));
            //headers[headers.length-1]=new BasicHeader("Cookie",HttpAutoUtils.getCookievalue(headercooks));
        }
        Header[] headers=new Header[headerList.size()];
        return headerList.toArray(headers);
    }

    /**
     * 设置响应结果
     * @param httpResPonseBean 要返回的响应结果
     * @param httpresponse httpclient返回的结果内容
     */
    private void setresponseinfo(HttpResPonseBean httpResPonseBean,CloseableHttpResponse httpresponse){
        if(httpresponse == null){
            return;
        }
        Header[] headers=httpresponse.getAllHeaders();
        httpResPonseBean.setRescode(httpresponse.getStatusLine()!=null?httpresponse.getStatusLine().getStatusCode():600);
        setResponseHeader(httpResPonseBean,headers);
        HttpEntity httpEntity=httpresponse.getEntity();
        if(httpEntity == null){
            logger.info("---->>>getEntity is null");
            return;
        }
        InputStream inputStream=null;
        try{
            inputStream=httpEntity.getContent();
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
            String s;
            StringBuilder buf=new StringBuilder();
            while ((s=bufferedReader.readLine())!=null){
                buf.append(s);
            }
            httpResPonseBean.setResinfo(buf.toString());
        }
        catch (Exception e){
            e.printStackTrace();
            logger.error("getContent is system error--->"+e);
        }
        finally {
            if(inputStream!=null){
                try{
                    inputStream.close();
                }
                catch (Exception e){
                    logger.error("inputStream close is system error -->"+e);
                }
            }
        }

    }


    /**
     * 往结果里set header值
     * @param response 要返回的响应内容
     * @param headers 请求返回的header
     */
    private void setResponseHeader(HttpResPonseBean response, Header[] headers){
        if(headers == null || headers.length<1){
            return;
        }
        Map<String,String> headermap=new HashMap<>();
        Map<String,String> cookmap=null;
        for(Header header:headers){
            String headername=header.getName();
            if(StringUtils.isNoneEmpty(headername) && headername.contains("Content-Type")){
                response.setRestype(getresponsetype(header.getValue())); //设置响应结果的数据类型
            }
            if(StringUtils.isNoneEmpty(headername) && headername.contains("Set-Cookie")){ //是cookie就单独处理哈
                if(cookmap == null){
                    cookmap=new HashMap<>();
                }
                setcookiemap(cookmap,header.getValue());
                continue;
            }
            headermap.put(headername,header.getValue());
        }
        response.setRescookie(cookmap);
        response.setResheader(headermap);
    }

    /**
     * 处理header里的cookie的值
     * @param cookmap 要返回的cookmap
     * @param cookvalue 响应返回的cookie的值，格式 BIDUPSID=C986EED6CBECDF2400D2978785E89BB6; PSTM=1564844039; BD_UPN=123253;
     */
    private void setcookiemap(Map<String,String> cookmap,String cookvalue){
        if(StringUtils.isEmpty(cookvalue)){
            return;
        }
        String[] cookkeyvalues=cookvalue.split(";");
        if(cookkeyvalues == null || cookkeyvalues.length<1){
            return;
        }
        for(String kvs:cookkeyvalues){
            String[] kv=kvs.split("=");
            if(kv == null || kv.length<2){
                continue;
            }
            cookmap.put(kv[0].trim(),kv[1]);
        }
    }


    private int getresponsetype(String headervalue){
        if(StringUtils.isEmpty(headervalue)){
            return -1;
        }
        if(headervalue.contains("text/html")){
            return 3;
        }
        if(headervalue.contains("application/json")){
            return 1;
        }
        return -1;
    }

    /**
     * 将参数拼接在get的url上面
     * @param url  类似格式/api/v4/clients?_like_clientid=ER-PC2
     * @param mapparam
     * @return
     */
    private String getUrlParam(String url,Map<String,String> mapparam){
        if(mapparam == null || mapparam.isEmpty()){
            return url;
        }
        if(url.contains("?")){
            return url+"&"+HttpAutoUtils.getGetParam(mapparam);
        }
        else {
            return url+"?"+HttpAutoUtils.getGetParam(mapparam);
        }
    }

    public static void main(String[] args) {
        HttpAutoClientService one=new HttpAutoClientService();
        Map<String,String> maps=new HashMap<>();
        one.setcookiemap(maps,"BIDUPSID=C986EED6CBECDF2400D2978785E89BB6; PSTM=1564844039; BD_UPN=123253;");
        System.out.println(maps.get("PSTM"));
    }
}
